package com.peoit.honeycomb.rest;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.peoit.honeycomb.application.ProjectApplication;
import com.peoit.honeycomb.domain.Accessory;
import com.peoit.honeycomb.domain.HoneycombProject;
import com.peoit.honeycomb.domain.Investment;
import com.peoit.honeycomb.domain.exception.AmountExcessiveException;
import com.peoit.honeycomb.domain.exception.ProjectNotExistException;
import com.peoit.honeycomb.domain.exception.ProjectNotInInvestStatus;
import com.peoit.honeycomb.domain.exception.UserNotExistException;
import com.peoit.honeycomb.dto.CommonResultDto;
import com.peoit.honeycomb.dto.Config;
import com.peoit.honeycomb.dto.InvestmentDto;
import com.peoit.honeycomb.dto.ProjectDto;
import com.peoit.honeycomb.dto.ProjectQueryDto;

/**
 * Created by Bing.Zeng on 2015/9/26.
 */
@Controller
@RequestMapping("/api/project")
public class ProjectResource extends BaseResource {
	Logger logger = Logger.getLogger(ProjectResource.class.getName());
	@Autowired
	ProjectApplication projectApplication;

	/**
	 * 发布项目
	 *
	 * @param projectPictures
	 * @param businessLicensePictures
	 * @param creditReportPictures
	 * @param businessPermissionPictures
	 * @param dto
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/createProject", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto createProject(
			@RequestParam(value = "projectPictures", required = false) MultipartFile[] projectPictures,
			@RequestParam(value = "businessLicensePictures", required = false) MultipartFile[] businessLicensePictures,
			@RequestParam(value = "creditReportPictures", required = false) MultipartFile[] creditReportPictures,
			@RequestParam(value = "businessPermissionPictures", required = false) MultipartFile[] businessPermissionPictures,
			ProjectDto dto, HttpServletRequest request) {
		CommonResultDto result = new CommonResultDto();
		try {

			HoneycombProject project = ProjectDto.toProject(dto);
			project.setStatus(Config.waitingVerified);

			// 依次处理处理各个上传文件

			Set<Accessory> accesories = new HashSet<>();
			// 项目图片
			if (projectPictures != null && projectPictures.length > 0) {
				for (MultipartFile file : projectPictures) {
					String filePath = this.storeUploadFile(request, file);
					Accessory accessory = new Accessory();
					accessory.setFilePath(filePath);
					accessory.setProject(project);
					accessory.setType(Config.PROJECT_PICTURE);
					accessory.setCreateTime(new Date());
					accesories.add(accessory);
				}
			}

			// 营业执照图片
			if (businessLicensePictures != null && businessLicensePictures.length > 0) {
				for (MultipartFile file : businessLicensePictures) {
					String filePath = this.storeUploadFile(request, file);
					Accessory accessory = new Accessory();
					accessory.setFilePath(filePath);
					accessory.setProject(project);
					accessory.setType(Config.BUSINESS_LICENSE);
					accessory.setCreateTime(new Date());
					accesories.add(accessory);
				}
			}

			// 个人信用报告图片
			if (creditReportPictures != null && creditReportPictures.length > 0) {
				for (MultipartFile file : creditReportPictures) {
					String filePath = this.storeUploadFile(request, file);
					Accessory accessory = new Accessory();
					accessory.setFilePath(filePath);
					accessory.setProject(project);
					accessory.setType(Config.PERSONAL_CREDIT_REPORT);
					accessory.setCreateTime(new Date());
					accesories.add(accessory);
				}
			}

			// 行业许可证图片
			if (businessPermissionPictures != null && businessPermissionPictures.length > 0) {
				for (MultipartFile file : businessPermissionPictures) {
					String filePath = this.storeUploadFile(request, file);
					Accessory accessory = new Accessory();
					accessory.setFilePath(filePath);
					accessory.setProject(project);
					accessory.setType(Config.BUSINESS_PERMISSION);
					accessory.setCreateTime(new Date());
					accesories.add(accessory);
				}
			}
			project.setAccessories(accesories);

			projectApplication.create(dto.getUserId(), project);

			result.setReason("success");
			result.setResult_code("200");
		} catch (UserNotExistException ex) {
			ex.printStackTrace();
			result.setReason("User not exist");
			result.setResult_code("401");
		} catch (Exception ex) {
			ex.printStackTrace();
			result.setReason("internal error: " + ex.getMessage());
			result.setResult_code("500");
		}
		return result;

	}

	/**
	 * 修改项目
	 * 
	 * @param projectPictures
	 * @param businessLicensePictures
	 * @param creditReportPictures
	 * @param businessPermissionPictures
	 * @param dto
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/updateProject", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto updateProject(
			@RequestParam(value = "projectPictures", required = false) MultipartFile[] projectPictures,
			@RequestParam(value = "businessLicensePictures", required = false) MultipartFile[] businessLicensePictures,
			@RequestParam(value = "creditReportPictures", required = false) MultipartFile[] creditReportPictures,
			@RequestParam(value = "businessPermissionPictures", required = false) MultipartFile[] businessPermissionPictures,
			ProjectDto dto, HttpServletRequest request) {
		CommonResultDto result = new CommonResultDto();
		try {

			HoneycombProject project = ProjectDto.toProject(dto);
			project.setId(dto.getId());
			project.setStatus(Config.waitingVerified);

			// 依次处理处理各个上传文件

			Set<Accessory> accesories = new HashSet<>();
			// 项目图片
			if (projectPictures != null && projectPictures.length > 0) {
				for (MultipartFile file : projectPictures) {
					String filePath = this.storeUploadFile(request, file);
					Accessory accessory = new Accessory();
					accessory.setFilePath(filePath);
					accessory.setProject(project);
					accessory.setType(Config.PROJECT_PICTURE);
					accessory.setCreateTime(new Date());
					accesories.add(accessory);
				}
			}

			// 营业执照图片
			if (businessLicensePictures != null && businessLicensePictures.length > 0) {
				for (MultipartFile file : businessLicensePictures) {
					String filePath = this.storeUploadFile(request, file);
					Accessory accessory = new Accessory();
					accessory.setFilePath(filePath);
					accessory.setProject(project);
					accessory.setType(Config.BUSINESS_LICENSE);
					accessory.setCreateTime(new Date());
					accesories.add(accessory);
				}
			}

			// 个人信用报告图片
			if (creditReportPictures != null && creditReportPictures.length > 0) {
				for (MultipartFile file : creditReportPictures) {
					String filePath = this.storeUploadFile(request, file);
					Accessory accessory = new Accessory();
					accessory.setFilePath(filePath);
					accessory.setProject(project);
					accessory.setType(Config.PERSONAL_CREDIT_REPORT);
					accessory.setCreateTime(new Date());
					accesories.add(accessory);
				}
			}

			// 行业许可证图片
			if (businessPermissionPictures != null && businessPermissionPictures.length > 0) {
				for (MultipartFile file : businessPermissionPictures) {
					String filePath = this.storeUploadFile(request, file);
					Accessory accessory = new Accessory();
					accessory.setFilePath(filePath);
					accessory.setProject(project);
					accessory.setType(Config.BUSINESS_PERMISSION);
					accessory.setCreateTime(new Date());
					accesories.add(accessory);
				}
			}
			project.setAccessories(accesories);

			projectApplication.updateProject(dto.getUserId(), project);

			result.setReason("success");
			result.setResult_code("200");
		} catch (UserNotExistException ex) {
			ex.printStackTrace();
			result.setReason("User not exist");
			result.setResult_code("401");
		} catch (Exception ex) {
			ex.printStackTrace();
			result.setReason("internal error: " + ex.getMessage());
			result.setResult_code("500");
		}
		return result;
	}

	/**
	 * 根据条件查询项目列表
	 *
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "/findProjects", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto findProject(ProjectQueryDto dto) {
		CommonResultDto result = new CommonResultDto();
		try {

			List<HoneycombProject> projetcs = projectApplication.findByWherePage(dto);

			List<ProjectDto> dtos = new ArrayList<>();
			for (HoneycombProject honeycombProject : projetcs) {
				dtos.add(ProjectDto.toDto(honeycombProject));
			}
			result.setResult(dtos);
			result.setReason("success");
			result.setResult_code("200");
		} catch (Exception ex) {
			ex.printStackTrace();
			result.setReason("internal error: " + ex.getMessage());
			result.setResult_code("500");
		}
		return result;
	}

	/**
	 * 分页查询用户关注的项目
	 *
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "/findConcernedProject", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto findConcernedProject(ProjectQueryDto dto) {
		CommonResultDto result = new CommonResultDto();
		try {

			List<HoneycombProject> projetcs = projectApplication.findConcernedProjectPage(dto.getAttentionId(),
					dto.getOffset(), dto.getPageSize());

			List<ProjectDto> dtos = new ArrayList<>();
			for (HoneycombProject honeycombProject : projetcs) {
				dtos.add(ProjectDto.toDto(honeycombProject));

			}
			result.setResult(dtos);
			result.setReason("success");
			result.setResult_code("200");
		} catch (UserNotExistException ex) {
			result.setReason("User not exist: " + ex.getMessage());
			result.setResult_code("401");
		} catch (Exception ex) {
			result.setReason("internal error: " + ex.getMessage());
			result.setResult_code("500");
		}
		return result;
	}

	/**
	 * 关注或者取消关注
	 *
	 * @param userId
	 * @param projectId
	 * @param concern
	 *            y/n
	 * @return
	 */
	@RequestMapping(value = "/concernProject", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto concernProject(String userId, String projectId, String concern) {
		CommonResultDto result = new CommonResultDto();
		try {

			projectApplication.concern(userId, projectId, concern);
			result.setReason("success");
			result.setResult_code("200");
		} catch (UserNotExistException ex) {
			ex.printStackTrace();
			result.setReason("user not exist: " + ex.getMessage());
			result.setResult_code("401");
		} catch (ProjectNotExistException ex) {
			ex.printStackTrace();
			result.setReason("project not exist  : " + ex.getMessage());
			result.setResult_code("402");
		} catch (IllegalStateException ex) {
			ex.printStackTrace();
			result.setReason(ex.getMessage());
			result.setResult_code("403");
		} catch (Exception ex) {
			ex.printStackTrace();
			result.setReason("internal error: " + ex.getMessage());
			result.setResult_code("500");
		}
		return result;
	}

	/**
	 * 用户是否关注了项目
	 *
	 * @param userId
	 * @param projectId
	 * @return
	 */
	@RequestMapping(value = "/isConcern", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto isConcern(String userId, String projectId) {
		CommonResultDto result = new CommonResultDto();
		try {
			Map<String, String> map = new HashMap();

			boolean isConcern = projectApplication.isConcern(userId, projectId);
			map.put("concern", isConcern ? "y" : "n");
			result.setReason("success");
			result.setResult_code("200");
			result.setResult(map);
		} catch (UserNotExistException ex) {
			ex.printStackTrace();
			result.setReason("user not exist: " + ex.getMessage());
			result.setResult_code("401");
		} catch (ProjectNotExistException ex) {
			ex.printStackTrace();
			result.setReason("project not exist  : " + ex.getMessage());
			result.setResult_code("402");
		} catch (IllegalStateException ex) {
			ex.printStackTrace();
			result.setReason(ex.getMessage());
			result.setResult_code("403");
		} catch (Exception ex) {
			ex.printStackTrace();
			result.setReason("internal error: " + ex.getMessage());
			result.setResult_code("500");
		}
		return result;
	}

	/**
	 * 投资项目
	 *
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "/invest", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto invest(InvestmentDto dto) {
		CommonResultDto result = new CommonResultDto();
		try {

			projectApplication.invest(dto);
			result.setReason("success");
			result.setResult_code("200");
		} catch (UserNotExistException ex) {
			ex.printStackTrace();
			result.setReason("user not exist: " + ex.getMessage());
			result.setResult_code("401");
		} catch (ProjectNotExistException ex) {
			ex.printStackTrace();
			result.setReason("project not exist  : " + ex.getMessage());
			result.setResult_code("402");
		} catch (IllegalStateException ex) {
			ex.printStackTrace();
			result.setReason(ex.getMessage());
			result.setResult_code("403");
		} catch (AmountExcessiveException ex) {
			ex.printStackTrace();
			result.setReason("Invest excessive amount " + ex.getMessage());
			result.setResult_code("405");
		} catch (ProjectNotInInvestStatus ex) {
			result.setReason("Project not in invest status " + ex.getMessage());
			result.setResult_code("406");
		} catch (Exception ex) {
			ex.printStackTrace();
			result.setReason("internal error: " + ex.getMessage());
			result.setResult_code("500");
		}
		return result;
	}

	/**
	 * 分页查询用户投资的项目
	 *
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "/findInvestedProject", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto findInvestedProject(ProjectQueryDto dto) {
		CommonResultDto result = new CommonResultDto();
		try {

			List<HoneycombProject> projetcs = projectApplication.findInvesteddProject(dto.getInvestorId(),
					dto.getOffset(), dto.getPageSize());

			List<ProjectDto> dtos = new ArrayList<>();
			for (HoneycombProject honeycombProject : projetcs) {

				ProjectDto projectDto = ProjectDto.toDto(honeycombProject);
				try {
					double investedByThisUser = 0.0;
					String userId = dto.getInvestorId();
					for (Investment investment : honeycombProject.getInvestments()) {
						if (userId.equals(investment.getUser().getId())) {
							investedByThisUser += investment.getAmount();
							projectDto.setUserInvestedDate(simpleDateFormat.format(investment.getCreateTime()));
						}
					}
					projectDto.setUserInvestedAmount(investedByThisUser);
				} catch (Exception ex) {
					ex.printStackTrace();
				}
				dtos.add(projectDto);

			}
			result.setResult(dtos);
			result.setReason("success");
			result.setResult_code("200");
		} catch (Exception ex) {
			ex.printStackTrace();
			result.setReason("internal error: " + ex.getMessage());
			result.setResult_code("500");
		}
		return result;
	}

	/**
	 * 查找用户投资的项目且该项目已成功
	 * 
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "findInvestedSuccessProject", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto findInvestedSuccessProject(ProjectQueryDto dto) {
		CommonResultDto result = new CommonResultDto();
		try {

			List<HoneycombProject> projetcs = projectApplication.findInvesteddSuccessProject(dto.getInvestorId(),
					dto.getOffset(), dto.getPageSize());

			List<ProjectDto> dtos = new ArrayList<>();
			for (HoneycombProject honeycombProject : projetcs) {

				ProjectDto projectDto = ProjectDto.toDto(honeycombProject);
				try {
					double investedByThisUser = 0.0;
					String userId = dto.getInvestorId();
					for (Investment investment : honeycombProject.getInvestments()) {
						if (userId.equals(investment.getUser().getId())) {
							investedByThisUser += investment.getAmount();
							projectDto.setUserInvestedDate(simpleDateFormat.format(investment.getCreateTime()));
						}
					}
					projectDto.setUserInvestedAmount(investedByThisUser);
				} catch (Exception ex) {
					ex.printStackTrace();
				}
				dtos.add(projectDto);

			}
			result.setResult(dtos);
			result.setReason("success");
			result.setResult_code("200");
		} catch (Exception ex) {
			ex.printStackTrace();
			result.setReason("internal error: " + ex.getMessage());
			result.setResult_code("500");
		}
		return result;
	}

	/**
	 * 支付保证金接口
	 *
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "/payMargin", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto payMargin(ProjectQueryDto dto) {
		CommonResultDto result = new CommonResultDto();
		try {
			projectApplication.payMargin(dto.getId());
			result.setReason("success");
			result.setResult_code("200");
		} catch (ProjectNotExistException pe) {
			result.setReason("project not exist  : " + pe.getMessage());
			result.setResult_code("402");
		} catch (Exception e) {
			result.setReason("internal error:" + e.getMessage());
			result.setResult_code("500");
		}
		return result;
	}

	/**
	 * 启动项目
	 *
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "/startProject", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto startProject(ProjectQueryDto dto) {
		CommonResultDto result = new CommonResultDto();
		try {
			projectApplication.startProject(dto);
			result.setReason("success");
			result.setResult_code("200");
		} catch (ProjectNotExistException pe) {
			result.setReason("project not exist  : :" + pe.getMessage());
			result.setResult_code("402");
		} catch (Exception e) {
			result.setReason("internal error:" + e.getMessage());
			result.setResult_code("500");
		}
		return result;
	}

	/**
	 * 取消项目
	 *
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "/cancelProject", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto cancelProject(ProjectQueryDto dto) {
		CommonResultDto result = new CommonResultDto();
		try {
			projectApplication.cancelProject(dto);
			result.setReason("success");
			result.setResult_code("200");
		} catch (ProjectNotExistException pe) {
			result.setReason("project not exist  : :" + pe.getMessage());
			result.setResult_code("402");
		} catch (Exception e) {
			result.setReason("internal error:" + e.getMessage());
			result.setResult_code("500");
		}
		return result;
	}

	/**
	 * 申请延期
	 *
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "/applyDelay", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto applyDelay(ProjectQueryDto dto) {
		CommonResultDto result = new CommonResultDto();
		try {
			result.setReason("success");
			result.setResult_code("200");
			projectApplication.applyDelay(dto);
			// TODO 像投资人发送信息
		} catch (ProjectNotExistException pe) {
			result.setReason("project not exist  : :" + pe.getMessage());
			result.setResult_code("402");
		} catch (Exception e) {
			result.setReason("internal error:" + e.getMessage());
			result.setResult_code("500");
		}
		return result;
	}

	/**
	 * 取消投资
	 * 
	 * @param projectId
	 * @param investId
	 * @return
	 */
	@RequestMapping(value = "/cancelInvest", method = RequestMethod.POST)
	public @ResponseBody CommonResultDto cancelInvest(String projectId, String investId) {
		CommonResultDto result = new CommonResultDto();
		try {
			projectApplication.cancelInvest(projectId, investId);
			result.setReason("success");
			result.setResult_code("200");
		} catch (UserNotExistException ue) {
			result.setReason("user not exist  : :" + ue.getMessage());
			result.setResult_code("401");
		} catch (ProjectNotExistException pe) {
			result.setReason("project not exist  : :" + pe.getMessage());
			result.setResult_code("402");
		} catch (Exception e) {
			result.setReason("internal error:" + e.getMessage());
			result.setResult_code("500");
		}
		return result;
	}

}
